#include "StdAfx.h"
#include "Ogre3DEngine.h"


Ogre3DEngine::Ogre3DEngine(void)
	:mOgreWindow(NULL),mCamera(NULL), mOgreRoot(NULL), mViewport(NULL), mSceneMgr(NULL), cameraMan(NULL)
{
}


Ogre3DEngine::~Ogre3DEngine(void)
{
	mOgreRoot->shutdown();
	delete mOgreRoot;
}


void Ogre3DEngine::init(void)
{
#ifdef _DEBUG
    mResourcesCfg = "resources_d.cfg";
    mPluginsCfg = "plugins_d.cfg";
#else
    mResourcesCfg = "resources.cfg";
    mPluginsCfg = "plugins.cfg";
#endif

    mOgreRoot = new Ogre::Root(mPluginsCfg);
	
	// Show the configuration dialog and initialise the system
    // You can skip this and use root.restoreConfig() to load configuration
    // settings if you were sure there are valid ones saved in ogre.cfg
	if(mOgreRoot->restoreConfig())
    {
        // Here we choose to let the system create a default rendering window by passing 'true'
        mOgreRoot->initialise(false);

    }
    else if(mOgreRoot->showConfigDialog())
    {
        // If returned true, user clicked OK so initialise
        // Here we choose to let the system create a default rendering window by passing 'true'
        mOgreRoot->initialise(false);
    }
}

void Ogre3DEngine::createOgreWindow(QWidget* widget)
{
  //== Creating and Acquiring Ogre Window ==//

	//windows handle

	Ogre::NameValuePairList params;
	params["externalWindowHandle"] = Ogre::StringConverter::toString((unsigned int)(widget->winId()));

	mOgreWindow = mOgreRoot->createRenderWindow( "QOgre2Widget_RenderWindow",
						   widget->width(),
						   widget->height(),
						   false,
						   &params );
	mOgreWindow->setActive(true);
}

void Ogre3DEngine::setupResources(void)
{
    // Load resource paths from config file
    Ogre::ConfigFile cf;
    cf.load(mResourcesCfg);

    // Go through all sections & settings in the file
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

    Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
}

void Ogre3DEngine::loadResources(void)
{
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}

void Ogre3DEngine::createSceneManagerAndCamera(QWidget* widget){

	//== Ogre Initialization ==//
	mSceneMgr = mOgreRoot->createSceneManager(Ogre::ST_GENERIC );
	mSceneMgr->setAmbientLight(Ogre::ColourValue(1.,1.,1.));

	mCamera = mSceneMgr->createCamera( "QOgre2Widget_Cam" );
	mCamera->setNearClipDistance(1);
	mCamera->setAspectRatio(Ogre::Real(widget->width()) / Ogre::Real(widget->height()));
	mCamera->setFixedYawAxis(false);

	cameraMan = new CameraEventsHandler(mCamera);
	

	mViewport = mOgreWindow->addViewport( mCamera );
	mViewport->setBackgroundColour( Ogre::ColourValue( 0,0,0 ) );
	mViewport->setClearEveryFrame(true);
}

void Ogre3DEngine::createScene(){

	mainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

	lightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
 	Ogre::Light* l = mSceneMgr->createLight("MainLight");
	lightNode->attachObject(l);
	lightNode->setPosition(Ogre::Vector3(20.,10.,40.));

	Ogre::Entity *mainEntity = mSceneMgr->createEntity("mainEntity","ogrehead.mesh");
	mainNode->attachObject(mainEntity);

	//paint axis
	paintAxis();
}

void Ogre3DEngine::paintAxis(){
	

	Ogre::ManualObject *XAxis = mSceneMgr->createManualObject("Xaxis"); 
	Ogre::ManualObject *YAxis = mSceneMgr->createManualObject("Yaxis"); 
	Ogre::ManualObject *ZAxis = mSceneMgr->createManualObject("Zaxis"); 

	mainNode->attachObject(XAxis);
	mainNode->attachObject(YAxis);
	mainNode->attachObject(ZAxis);

	XAxis -> begin("red", Ogre::RenderOperation::OT_LINE_LIST);	
		XAxis -> position(Ogre::Vector3(0.,0.,0.));
		XAxis -> position(Ogre::Vector3(500.,0.,0.));
	XAxis->end();

	YAxis -> begin("green", Ogre::RenderOperation::OT_LINE_LIST);	
		YAxis -> position(Ogre::Vector3(0.,0.,0.));
		YAxis -> position(Ogre::Vector3(0.,500.,0.));
	YAxis->end();

	ZAxis -> begin("blue", Ogre::RenderOperation::OT_LINE_LIST);	
		ZAxis -> position(Ogre::Vector3(0.,0.,0.));
		ZAxis -> position(Ogre::Vector3(0.,0.,500.));
	ZAxis->end();

}

bool Ogre3DEngine::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	cameraMan->frameRenderingQueued(evt);
	return true;
}

CameraEventsHandler* Ogre3DEngine::getCameraHandler()
{
	return cameraMan;
}

Ogre::Root* Ogre3DEngine::getOgreRoot()
{
	return mOgreRoot;
}

Ogre::RenderWindow* Ogre3DEngine::getOgreWindow()
{
	return mOgreWindow;
}